package crp.core.portal.domain.services;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qwlabs.lang.C2;
import crp.core.course.domain.models.CourseEntity;
import crp.core.portal.domain.models.PortalSectionCourseLoadContext;
import crp.core.portal.domain.models.PortalSectionLoadStrategy;
import io.quarkus.arc.DefaultBean;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.List;
import java.util.Map;

@ApplicationScoped
@DefaultBean
public class PortalSectionCourseLoadDispatcher implements PortalSectionCourseLoader {
    private final Map<PortalSectionLoadStrategy, PortalSectionCourseLoader> loaders;

    @Inject
    public PortalSectionCourseLoadDispatcher(
            PortalSectionCourseFixedLoader fixedLoader,
            PortalSectionCourseViewsLoader viewsLoader,
            PortalSectionCourseLatestLoader latestLoader) {
        this.loaders = Map.of(
                PortalSectionLoadStrategy.FIXED, fixedLoader,
                PortalSectionLoadStrategy.VIEWS, viewsLoader,
                PortalSectionLoadStrategy.LATEST, latestLoader);
    }

    public Map<String, List<CourseEntity>> load(PortalSectionCourseLoadContext context) {

        Map<PortalSectionLoadStrategy, PortalSectionCourseLoadContext> byStrategyContexts =
                C2.map(context.getSections(),
                        PortalSectionCourseLoadContext.SectionWithConfig::getLoadStrategy,
                        () -> new PortalSectionCourseLoadContext(Lists.newArrayList(), context.getLimit(), context.getPublicStatuses()),
                        PortalSectionCourseLoadContext::merge
                );
        Map<String, List<CourseEntity>> courses = Maps.newHashMap();
        byStrategyContexts.forEach(((loadStrategy, c) ->
                courses.putAll(this.loaders.get(loadStrategy).load(c))));
        return courses;
    }
}
